#include "DrawHelper.h"

DrawHelper DrawHelper::dhInstance;

DrawHelper::DrawHelper()
{
    #if defined(_DEBUG)
    std::cout << "DrawHelper constructed." << std::endl;
    #endif
}

DrawHelper& DrawHelper::Instance()
{
    return dhInstance;
}

void DrawHelper::drawLine2D(float startX, float startY, float endX, float endY, Color* c)
{
    glBindTexture(GL_TEXTURE_2D, 0);
    glColor4f(c->red, c->green, c->blue, c->alpha);
    glBegin(GL_LINES);
        glVertex2f(startX, startY);
        glVertex2f(endX, endY);
    glEnd();
}

// Filled or unfilled 2D rectangle
void DrawHelper::drawRect2D(float startX, float startY, float endX, float endY, Color* c, bool isFilled)
{
    glBindTexture(GL_TEXTURE_2D, 0);
    if(isFilled)
    {
        glColor4f(c->red, c->green, c->blue, c->alpha);
        glRectf(startX, startY, endX, endY); // This call is faster than defining all the verticies by hand.
    }
    else
    {
        glColor4f(c->red, c->green, c->blue, c->alpha);
        glBegin(GL_LINE_LOOP);
            glVertex2f(startX, startY+1.0f); // startY+1.0f fixes 2D rasterization side-effect.
            glVertex2f(startX, endY);
            glVertex2f(endX, endY);
            glVertex2f(endX, startY);
        glEnd();
    }
}

// Textured 2D rectangle
void DrawHelper::drawRect2D(float startX, float startY, float endX, float endY, Color* c, Texture2D* texture)
{
    glBindTexture(GL_TEXTURE_2D, texture->ID);
    glColor4f(c->red, c->green, c->blue, c->alpha);
    glBegin(GL_QUADS);
        glVertex2f(startX, startY);glTexCoord2f(1.0f, 0.0f);
        glVertex2f(startX, endY);glTexCoord2f(0.0f, 0.0f);
        glVertex2f(endX, endY);glTexCoord2f(0.0f, 1.0f);
        glVertex2f(endX, startY);glTexCoord2f(1.0f, 1.0f);
    glEnd();
}

void DrawHelper::drawStr2D(std::string str, int fontSize, float x, float y, Color* c, Texture2D* texture)
{
    drawStr2D(str, fontSize, x, y, c, texture, 0);
}

void DrawHelper::drawStr2D(std::string str, int fontSize, float x, float y, Color* c, Texture2D* texture, int spacing)
{
    RectType* temp = new RectType(0.0f, 0.0f, 0.0626f, 0.0625f);
    glBindTexture(GL_TEXTURE_2D, texture->ID);
    glColor4f(c->red, c->green, c->blue, c->alpha);
    glBegin(GL_QUADS);
        for (unsigned int i = 0; i < str.length(); i++)
        {
            if (i != 0)
                x += fontSize + spacing; // Make spacing adjustments
            //temp = asciiLookup((int)str[i]);
            temp->x = ((int)str[i]%16)*temp->width;
            temp->y = ((int)str[i]/16)*temp->height;
            // Top right
            glTexCoord2f(temp->x+temp->width, temp->y);
            glVertex2f(x+fontSize, y);
            // Bottom Right
            glTexCoord2f(temp->x+temp->width, temp->y+temp->height);
            glVertex2f(x+fontSize, y+fontSize);
            // Bottom Left
            glTexCoord2f(temp->x, temp->y+temp->height);
            glVertex2f(x, y+fontSize);
            // Top Left
            glTexCoord2f(temp->x, temp->y);
            glVertex2f(x, y);
        }
    delete temp;
    glEnd();
}

// Using this in drawStr2D can lead to massive memory leaks if pointers
// are not cleaned up. (It is also difficult to clean up the pointers.)
RectType* DrawHelper::asciiLookup(int value)
{

    RectType* temp = new RectType(0.0f, 0.0f, 0.0626f, 0.0625f);

    // Row
    temp->x = (value%16)*temp->width;
    // Column
    temp->y = (value/16)*temp->height;

    return temp;
}
